/**
 * 
 */
package com.volatileengine.datatypes;

import java.nio.ByteBuffer;

import javax.vecmath.Color4f;
import javax.vecmath.Quat4f;
import javax.vecmath.Tuple2f;
import javax.vecmath.Tuple3f;

import com.volatileengine.VolatileEngineException;
import com.volatileengine.platform.CreateVertexBufferObjectReadCommand;
import com.volatileengine.platform.GPUChannel;
import com.volatileengine.platform.PlatformManager;
import com.volatileengine.resources.references.Handle;
import com.volatileengine.resources.references.Resource;

/**
 * @author Ahmed
 * 
 */
public class AcceleratedArray<T extends ByteBuffer> extends AbstractArray<T> implements Resource {

	private AbstractArray<T> encapsulatedArray;
	private boolean element;

	private Handle<?> handle;

	private int stride, offset, chunkSize, length;
	private DataType datatype;

	private AcceleratedArray(AbstractArray<T> array, boolean element) {
		this.encapsulatedArray = array;
		this.stride = array.getStride();
		this.length = array.getLength();
		this.offset = array.getOffset();
		this.chunkSize = array.getChunkSize();
		this.datatype = array.getType();
		this.element = element;
	}

	@Override
	/*
	 * * Creates the underlying encapsulatedArray
	 */
	public void clearBuffer() {
		encapsulatedArray = null;

	}

	@Override
	public void copyFrom(ByteBuffer buffer) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public void copyInto(ByteBuffer buffer) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void createBuffer() {
		if (handle != null) {
			throw new VolatileEngineException("AccelerateArray has already been created");
		}
		GPUChannel channel = new GPUChannel();
		PlatformManager.instance().openChannel(channel);
		CreateVertexBufferObjectReadCommand vbo = new CreateVertexBufferObjectReadCommand(this);
		channel.put(vbo);
		channel.sync();
		PlatformManager.instance().closeChannel(channel);
	}

	@Override
	public T getBuffer() {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public int getBufferIndex(int index) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public byte getByte(int index, int offset) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public int getChunkSize() {
		return chunkSize;
	}

	@Override
	public Color4f getColor4f(int index, int offset, Color4f target) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public float getFloat(int index, int offset) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public int getInt(int index, int offset) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public int getLength() {
		return length;
	}

	@Override
	public int getOffset() {
		return offset;
	}

	@Override
	public Quat4f getQuat4f(int index, int offset, Quat4f target) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public int getStride() {
		return stride;
	}

	@Override
	public Tuple2f getTuple2f(int index, int offset, Tuple2f target) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public Tuple3f getTuple3f(int index, int offset, Tuple3f target) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");
	}

	@Override
	public DataType getType() {
		return datatype;
	}

	@Override
	public void setByte(int index, int offset, byte value) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setColor4f(int index, int offset, Color4f source) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setFloat(int index, int offset, float value) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setInt(int index, int offset, int value) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setLength(int length) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setQuat4f(int index, int offset, Quat4f source) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setTuple2f(int index, int offset, Tuple2f source) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public void setTuple3f(int index, int offset, Tuple3f source) {
		throw new IllegalStateException("Cannot call this method on an AcceleratedArray");

	}

	@Override
	public Handle<?> getHandle() {
		return handle;
	}

	/**
	 * @return the element
	 */
	public boolean isElement() {
		return element;
	}

	/**
	 * @return the encapsulatedArray
	 */
	public AbstractArray<T> getEncapsulatedArray() {
		return encapsulatedArray;
	}

}
